package com.hzy.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.time.DateUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.auth0.jwt.impl.PublicClaims.ISSUER;


/**
 * @author whc
 */
public class JWTUtils {
    private static final byte[] SECURE_KEY = "iCEVQAeehiiyXNSwuxmEGO7I7h5PAGVm".getBytes();

    private static JWTUtils mInstance;

    private JWTUtils() {
    }

    public static JWTUtils getInstance() {
        if (mInstance == null) {
            mInstance = new JWTUtils();
        }
        return mInstance;
    }

    public String createToken(Map<String, String> claims) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECURE_KEY);
            JWTCreator.Builder builder = JWT.create().withIssuer(ISSUER)
                                            //设置过期时间为1年
                                            .withExpiresAt(DateUtils.addYears(new Date(), 1));
            claims.forEach(builder::withClaim);
            return builder.sign(algorithm);
        } catch (IllegalArgumentException e) {
            throw new TokenRuntimeException("生成token失败");
        }

    }

    public Map<String, String> verifyToken(String token) throws TokenException {
        Algorithm algorithm;
        Map<String, Claim> map;
        try {
            algorithm = Algorithm.HMAC256(SECURE_KEY);
            JWTVerifier verifier = JWT.require(algorithm).withIssuer(ISSUER).build();
            DecodedJWT jwt = verifier.verify(token);
            map = jwt.getClaims();
        } catch (Exception e) {
            throw new TokenException("鉴权失败");
        }
        Map<String, String> resultMap = new HashMap<>(map.size());
        map.forEach((k, v) -> resultMap.put(k, v.asString()));
        return resultMap;
    }

    public static class TokenException extends Exception {
        TokenException(String msg) {
            super(msg);
        }
    }

    public static class TokenRuntimeException extends RuntimeException {
        TokenRuntimeException(String msg) {
            super(msg);
        }
    }

}
